//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//********************************************************* 

using System.IO;

namespace Microsoft.TridentWordAddIn.Common
{
    public sealed class StreamHelper
    {
        /// <summary>
        /// STORE BUFFER LENGHT
        /// </summary>
        public const int BufferLength = 8192;

        /// <summary>
        /// Prevents a default instance of the {StreamHelper} class from being created
        /// </summary>
        private StreamHelper()
        {
        }

        /// <summary>
        /// Gets a memory stream with the contents of the input stream.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <returns>a <c>MemoryStream</c> with the contents of the input stream</returns>
        public static MemoryStream GetMemoryStream(Stream input)
        {
            if (input == null)
            {
                return new MemoryStream();
            }

            MemoryStream memStream = new MemoryStream();
            byte[] buffer = new byte[BufferLength];
            int bytesRead = 0;

            do
            {
                bytesRead = input.Read(buffer, 0, BufferLength);
                memStream.Write(buffer, 0, bytesRead);
            } while (bytesRead != 0);

            buffer = null;
            memStream.Position = 0;
            return memStream;
        }

        /// <summary>
        /// Gets the memory stream.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <returns>MemoryStream</returns>
        public static MemoryStream GetMemoryStream(string filePath)
        {
            if (File.Exists(filePath))
            {
                using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    return StreamHelper.GetMemoryStream(fs);
                }
            }

            return null;
        }

        /// <summary>
        /// Gets the chunk data.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="dataLength">Length of the data.</param>
        /// <returns>Stream</returns>
        public static Stream GetChunkData(Stream input, int dataLength)
        {
            int readSize = 0;
            int totalReadSize = 0;
            byte[] buffer = new byte[BufferLength];
            Stream tempStream = new MemoryStream();
            do
            {
                readSize = input.Read(buffer, 0, BufferLength);
                if (readSize <= 0)
                {
                    break;
                }

                tempStream.Write(buffer, 0, readSize);
                totalReadSize += readSize;
            } while (totalReadSize < dataLength);

            return tempStream;
        }

        /// <summary>
        /// Writes to file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="data">The data.</param>
        public static void WriteToFile(string fileName, byte[] data)
        {
            using (FileStream fileStream = new FileStream(fileName, FileMode.Create))
            {
                using (BinaryWriter bw = new BinaryWriter(fileStream))
                {
                    bw.Write(data);
                }
            }
        }

        /// <summary>
        /// Copies the stream.
        /// </summary>
        /// <param name="sourceStream">The source stream.</param>
        /// <param name="destinationStream">The destination stream.</param>
        public static void CopyStream(Stream sourceStream, Stream destinationStream)
        {
            byte[] buffer = new byte[BufferLength];
            int numBytes;

            using (BinaryReader binaryReader = new BinaryReader(sourceStream))
            {
                while ((numBytes = binaryReader.Read(buffer, 0, BufferLength)) > 0)
                {
                    destinationStream.Write(buffer, 0, numBytes);
                }
            }
        }
    }
}
